package com.example.dingdong.service;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import com.alibaba.fastjson.JSONObject;
import com.example.dingdong.daomain.AdminEntity;
import com.example.dingdong.daomain.BasicUserEntity;
import com.example.dingdong.daomain.BossEntity;
import com.example.dingdong.daomain.ClientEntity;
import com.example.dingdong.daomain.RoleEntity;
import com.example.dingdong.repository.AdminRepository;
import com.example.dingdong.repository.BasicUserRepository;
import com.example.dingdong.repository.BossRepository;
import com.example.dingdong.repository.ClientRepository;
import com.example.dingdong.repository.RoleRepository;
import com.example.dingdong.shiro.CustomCredentialsMatcher;
import com.example.dingdong.util.MyException;
import com.example.dingdong.websocketService.WebSocketService;

/**
 * 
 * @ClassName: UserService
 * @Description: 用户Service层
 * @Author :chengwenixng
 * @DateTime 2021-08-02 16:17:35
 */
@Service
public class BasicUserService {
	private static final Logger log = LoggerFactory.getLogger(BasicUserService.class);

	@Autowired
	private BasicUserRepository userRepository;
	@Autowired
	private WebSocketService webSocketService;
	@Autowired
	CustomCredentialsMatcher customCredentialsMatcher;
	@Autowired
	AdminRepository adminRepository;
	@Autowired
	RoleRepository roleRepository;
	@Autowired
	BossRepository bossRepository;
	@Autowired
	ClientRepository clientRepository;


	/**
	 * 
	 * @Title: login
	 * @Description: 用户登录
	 * @Author coding
	 * @DateTime 2021-08-04 14:37:41
	 * @param account
	 * @param password
	 * @param remoteIp
	 * @throws Exception
	 */
	public void login(String account, String password, String remoteIp) throws Exception {
		/**
		 * 1、获取Subject单例对象
		 */
		Subject currentUser = SecurityUtils.getSubject();
		if (currentUser.isAuthenticated()) {
			currentUser.logout();
			log.info("用户已经登录!");
			
			// 获取账号对应的 session 连接
			String tokenId = webSocketService.getAccountrelateIpAddress().get(account);
			WebSocketSession session = (tokenId == null) ? null : webSocketService.getSessions().get(tokenId);
			if (session != null) {
				if(session.isOpen()) {
					JSONObject sendMsg = new JSONObject();
					sendMsg.put("message", "账号在其他地方登录");
					JSONObject jobj = new JSONObject();
					jobj.put("type", "userLoginOut");
					jobj.put("data", sendMsg);
					synchronized (session) {
						session.sendMessage(new TextMessage(jobj.toJSONString().getBytes()));
					}
					log.error("账号在其他地方登陆");
					session.close();
				}
				
			}
			// 删除账号对应token
			webSocketService.getAccountrelateIpAddress().remove(account);
		}
		/**
		 * 2、使用用户的登录信息创建令牌
		 */
		UsernamePasswordToken token = new UsernamePasswordToken(account, password);
		currentUser.login(token);
		/**
		 * 3、设置过期时间
		 */
		currentUser.getSession().setTimeout(3 * 60 * 60 * 1000L);
		log.info("用户登录成功，登录 IP: " + remoteIp + "当前登录人数：" + customCredentialsMatcher.getSessionMap().size());

	}
	/**
	 * 
	 * @Title: getUser
	 * @Description: 注册账号
	 * @Author coding
	 * @DateTime 2021-08-04 15:18:11
	 * @param req
	 * @throws Exception
	 */
	public void getUser(JSONObject req ) throws Exception {
		/********** 1、校验数据 **********/
		String account =  req.getString("account");
		String password = req.getString("password");
		//判断该账号是否注册
		BasicUserEntity basicUserEntity = new BasicUserEntity();
		if (userRepository.findByAccountAndDelFlag(account, true)!= null) {
			throw new MyException("该账号账号已经被注册，请更换后重试！");
		}
		//保存账号密码
		RoleEntity roleEntity = new RoleEntity();
		int typeId = (int) req.get("typeId");
		basicUserEntity.setAccount(account);
		basicUserEntity.setPassword(password);
		if(typeId == 0) {
			// 1.1 先保存用户
			AdminEntity adminEntity = new AdminEntity();
			adminRepository.save(adminEntity);
			basicUserEntity.setAdminEntity(adminEntity);
			// 1.2 查找到相应的角色角色
			roleEntity = roleRepository.findByIdAndDelFlag(1, true);
		}else if(typeId == 1) {
			// 2.1 先保存用户
			ClientEntity clientEntity = new  ClientEntity();
			clientRepository.save( clientEntity);
			basicUserEntity.setClientEntity(clientEntity);
			// 2.2 查找到相应的角色角色
			roleEntity = roleRepository.findByIdAndDelFlag(2, true);
		}else if(typeId == 2) {
			// 3.1 先保存用户
			BossEntity  bossEntity= new BossEntity();
			bossRepository.save(bossEntity);
			basicUserEntity.setBossEntity( bossEntity);;
			// 3.2 查找到相应的角色角色
			roleEntity = roleRepository.findByIdAndDelFlag(3, true);	
	 }
		// 4.1设置角色
		basicUserEntity.setRoleEntity(roleEntity);
		System.out.println(basicUserEntity);
		startSavaBasicUserEntity(basicUserEntity);
  }
	/**
	 * 
	 * @Title: isLogin
	 * @Description: 获取登录状态
	 * @Author coding
	 * @DateTime 2021-08-04 15:22:20
	 * @return
	 */
	public boolean isLogin() {
		// 获取当前的subject
		Subject currentuser = SecurityUtils.getSubject();
		// 判断是否已经登陆
		if (currentuser.isAuthenticated()) {
			
			System.out.println("=>>>>>>>>>>>>"+currentuser.isAuthenticated());
			log.info("用户已经登陆！");
			return true;
		} else {
			log.info("用户未登陆！");
			return false;
		}
	}
	/**
	 * 
	 * @Title: logout
	 * @Description:注销账号 
	 * @Author coding
	 * @DateTime 2021-08-04 15:23:42
	 * @throws Exception
	 */
	public void logout()throws Exception{
		//获取用户信息
		Subject currentUser = SecurityUtils.getSubject();
		//判断用户已经登录
		if(!currentUser.isAuthenticated()  ) {
			return;
		}
		// 3、删除 websocket 中token值
		String account =  currentUser.getSession().getAttribute("account").toString();
		webSocketService.getAccountrelateIpAddress().remove(account);
		// 4、注销登录
		 currentUser.logout();
		log.info("用户注销成功！");
	}
	/**
	 * 
	 * @Title: editPassword
	 * @Description: 修改密码
	 * @Author coding
	 * @DateTime 2021-08-04 15:28:27
	 * @param req
	 * @throws Exception
	 */
	public void editPassword(JSONObject req ) throws Exception {
		/********** 1、校验数据 **********/
		String account =  req.getString("account");
		String password = req.getString("password");
		BasicUserEntity basicUserEntity =userRepository.findByAccountAndDelFlag(account, true);
		if ( basicUserEntity == null) {
			throw new Exception("该账号不存在，请重试！");
		}
		//保存数据
		basicUserEntity.setPassword(password);
		userRepository.save(basicUserEntity);
	}
	/**
	 * 获取当前登录用户
	 * @return
	 * @throws Exception
	 */
	
	public BasicUserEntity getLoginUser() throws Exception {
		Subject currentuser = SecurityUtils.getSubject();
		if (!currentuser.isAuthenticated()) {
			throw new Exception("用户未登录");
		}
		String account = currentuser.getSession().getAttribute("account").toString();
		BasicUserEntity basicUserEntity =userRepository.findByAccountAndDelFlag(account, true);
		if(basicUserEntity == null) {
			throw new Exception("不存在数据库");
		}
		return basicUserEntity;
	}
	/**
	 * 
	 * @Title: getAllBasicUserDatas
	 * @Description: 获取所有用户信息
	 * @Author coding
	 * @DateTime 2021-08-06 20:38:14
	 * @return
	 * @throws Exception
	 */
	public List<BasicUserEntity> getAllBasicUserDatas() throws Exception{
		Subject currentuser = SecurityUtils.getSubject();
		if (!currentuser.isAuthenticated()) {
			throw new Exception("用户未登录");
		}
		return userRepository.findByDelFlag(true);
	}
	/**
	 * 
	 * @Title: getBasicUserEntity
	 * @Description: 根据id查询数据
	 * @Author coding
	 * @DateTime 2021-08-06 21:08:51
	 * @param id
	 * @param delFlag
	 * @return
	 */
	public BasicUserEntity  getBasicUserEntity(Long id, boolean delFlag) {
		return userRepository.findByIdAndDelFlag(id, true);
	}
	
	/**
	 * 
	 * @Title: startSavaBasicUserEntity
	 * @Description: 开始保存数据
	 * @Author coding
	 * @DateTime 2021-08-06 21:08:59
	 * @param basicUserEntity
	 * @return
	 */
	public BasicUserEntity startSavaBasicUserEntity(BasicUserEntity  basicUserEntity) {
		return  userRepository.save(basicUserEntity);
	}
	
}
